<?php
namespace App\Services\ThirdPayments\Recharge;

use App\Lib\PaymentMap;
use App\Lib\ThirdPartyMap;
use App\Models\RechargeOrder;
use App\Services\ThirdPayments\BankTraits\YIKABankMap;
use App\Services\ThirdPayments\Contracts\Actions\HrefRedirectAction;
use App\Services\ThirdPayments\Contracts\Actions\QrCodeAction;
use App\Services\ThirdPayments\Contracts\QRCapable;
use App\Services\ThirdPayments\Contracts\RechargeBaseAbstract;
use App\Services\ThirdPayments\Contracts\WAPable;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;

class YIKAPayment extends RechargeBaseAbstract implements WAPable, QRCapable
{
    use YIKABankMap;

    protected $gw_pay = 'http://www.1983game.com/Bank';
    protected $gw_query = 'http://www.1983game.com/search.ashx';

    public function callback(array $data)
    {
        // TODO: Implement callback() method.
        if ($data['opstate'] == 0) {
            if ($this->veryCallbackSign($data)) {
                return true;
            }
        }
        return false;
    }

    public function veryCallbackSign(array $data)
    {
        // TODO: Implement veryCallbackSign() method.
        $signStr  = 'orderid=' . $data['orderid'] . '&';
        $signStr .= 'opstate=' . $data['opstate'] . '&';
        $signStr .= 'ovalue=' . $data['ovalue'] . '&';
        $signStr .= $this->getMchKey();
        if ($data['sign'] == md5($signStr)) {
            return true;
        }
        return false;
    }

    public function getOrderNoFromCallback(array $data)
    {
        // TODO: Implement getOrderNoFromCallback() method.
        return $data['orderid'];
    }

    public function getOrderAmtFromCallback(array $data)
    {
        // TODO: Implement getOrderAmtFromCallback() method.
        return $data['ovalue'];
    }

    public function getThirdNoFromCallback(array $data)
    {
        return $data['sysorderid'];
    }

    /**
     * @return mixed
     */
    public function getIdentify(): string
    {
        // TODO: Implement getIdentify() method.
        return ThirdPartyMap::YIKA;
    }

    /**
     *  needs child to achieve
     */
    public function initPaymentMap(): array
    {
        // TODO: Implement initPaymentMap() method.
        return [
            PaymentMap::WX => '1004',
            PaymentMap::ALI => '992',
            PaymentMap::WX_WAP => '1007',
            PaymentMap::ALI_WAP => '1006',
            PaymentMap::BANK => '1000',
            PaymentMap::BANK_WAP => '1005',
            PaymentMap::QQ => '1008'
        ];
    }

    public function query(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement query() method.
        $this->setParameter('orderid', $rechargeOrder->plat_no);
        $this->setParameter('parter', $this->getMchId());
        $this->setParameter('sign', $this->querySign());
        $res = curlHttp($this->getGwQuery(), $this->getParameters());
        return $res['body'];
    }

    public function bankHref(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement bankHref() method.
        $this->initParameters($rechargeOrder);
        return $this->getGwPay() . '?' . http_build_query($this->getParameters());
    }

    public function scanCode(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement scanCode() method.
        $this->initParameters($rechargeOrder);
        $href = $this->getGwPay() . '?' . http_build_query($this->getParameters());
        return $href;
    }

    public function paySign(): string
    {
        // TODO: Implement paySign() method.
        $signStr = 'parter=' . $this->getMchId() . '&';
        $signStr .= 'type=' . $this->getParameter('type') . '&';
        $signStr .= 'value=' . $this->getParameter('value') . '&';
        $signStr .= 'orderid=' . $this->getParameter('orderid') . '&';
        $signStr .= 'callbackurl=' . $this->getParameter('callbackurl');
        $signStr .= $this->getMchKey();
        return md5($signStr);
    }

    public function querySign(): string
    {
        // TODO: Implement querySign() method.
        $signStr = 'orderid=' . $this->getParameter('orderid');
        $signStr .= 'parter=' . $this->getMchId();
        $signStr .= $this->getMchKey();
        return md5($signStr);
    }

    public function showSuccess(): string
    {
        // TODO: Implement showSuccess() method.
        return 'opstate=0';
    }

    public function initParameters(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement initParameters() method.
        $this->setParameter('parter', $this->getMchId());
        $mchData = $rechargeOrder->order_data;
        if ($mchData['recharge_type'] == PaymentMap::BANK) {
            $type = $this->getBank($mchData['bank_code']) ? : '1000';
        } else {
            $type = $this->getPaymentMap($mchData['recharge_type']);
        }
        $this->setParameter('type', $type);
        $this->setParameter('value', $rechargeOrder->order_amt);
        $this->setParameter('orderid', $rechargeOrder->plat_no);
        $this->setParameter('callbackurl', $this->getCallbackUrl());
        $this->setParameter('hrefbackurl', $this->getReturnUrl());
        $this->setParameter('attach', $this->getRemark($rechargeOrder));
        $this->setParameter('sign', $this->paySign());
    }

    public function wapReq(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement wapReq() method.
        $this->initParameters($rechargeOrder);
        $url = $this->getGwPay() . '?' . http_build_query($this->getParameters());
        return new HrefRedirectAction($url);
    }

    public function qrCode(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement qrCode() method.
        $this->initParameters($rechargeOrder);
        $qrCode = '';
        $res = curlHttp($this->getGwPay(), $this->getParameters(), 'get', 0, true);
        if ($this->curlResVerify($this, $res)) {
            $parse = parse_url($res['url'], PHP_URL_QUERY);
            parse_str($parse, $params);
            $qrCode = array_key_exists('data', $params) ? $params['data']: $qrCode;
            return new QrCodeAction(iconv('GB2312', 'UTF-8//IGNORE', $qrCode));
        }
    }
}
